package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author atguigu-mqx
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Override
    public void addCart(Long skuId, String userId, Integer skuNum) {
        /*
        存储购物车数据： redis  hash： hset key=user:userId:cart  field=skuId  value=cartInfo ;
        1.  先判断购物车中是否有该商品！
            true:   update数量相加：
                    默认选中：
                    赋值修改时间：
            false:  insert
        2.  添加购物车时，购物车有没有这个商品，默认都是选中状态！
            添加的时候应该有会添加时间，修改时间。

        3.  redis

         */
        //  组成购物车的key
        String cartKey = getCartKey(userId);
        //  根据skuId 获取数据 hget key field
        CartInfo cartInfoExist = (CartInfo) this.redisTemplate.opsForHash().get(cartKey, skuId.toString());
        //  cartInfoExist = null
        //  cartInfoExist = new CartInfo();
        //  hget key field
        //  CartInfo cartInfoExist1 = (CartInfo) this.redisTemplate.boundHashOps(cartKey).get(skuId.toString());

        //  判断购物车中是否有购物项！
        //  Boolean res = this.redisTemplate.opsForHash().hasKey(cartKey, skuId.toString());
        //  Boolean result = this.redisTemplate.boundHashOps(cartKey).hasKey(skuId.toString());

        //  判断
        if (cartInfoExist != null) {
            //  说明购物车中已经存在！
            //            if (cartInfoExist.getSkuNum()>200){
            //                cartInfoExist.setSkuNum(200);
            //            }
            cartInfoExist.setSkuNum(cartInfoExist.getSkuNum() + skuNum);
            //  默认选中!
            if (cartInfoExist.getIsChecked().intValue() == 0) {
                cartInfoExist.setIsChecked(1);
            }
            //  可选的操作：
            cartInfoExist.setSkuPrice(this.productFeignClient.getSkuPrice(skuId));
            //  修改更新时间
            cartInfoExist.setUpdateTime(new Date());
            //  将最新数据放入缓存！ hset key field value;
            //  this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfoExist);
        } else {
            //  商品不存在！根据skuId 查询skuInfo ;
            SkuInfo skuInfo = this.productFeignClient.getSkuInfo(skuId);
            //  创建对象
            cartInfoExist = new CartInfo();
            cartInfoExist.setSkuId(skuId);
            cartInfoExist.setSkuNum(skuNum);
            //  实时价格
            cartInfoExist.setSkuPrice(this.productFeignClient.getSkuPrice(skuId));
            cartInfoExist.setCartPrice(this.productFeignClient.getSkuPrice(skuId));
            cartInfoExist.setSkuName(skuInfo.getSkuName());
            cartInfoExist.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfoExist.setUserId(userId);
            cartInfoExist.setCreateTime(new Date());
            cartInfoExist.setUpdateTime(new Date());
            //            CartInfo cartInfo = new CartInfo();
            //            cartInfo.setSkuId(skuId);
            //            cartInfo.setSkuNum(skuNum);
            //            //  实时价格
            //            cartInfo.setSkuPrice(this.productFeignClient.getSkuPrice(skuId));
            //            cartInfo.setCartPrice(this.productFeignClient.getSkuPrice(skuId));
            //            cartInfo.setSkuName(skuInfo.getSkuName());
            //            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            //            cartInfo.setUserId(userId);
            //            cartInfo.setCreateTime(new Date());
            //            cartInfo.setUpdateTime(new Date());

            //  将插入数据放入缓存！ hset key field value;
            //  this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfo);
            //  cartInfoExist = cartInfo;
        }

        //  将数据放入缓存！
        this.redisTemplate.opsForHash().put(cartKey, skuId.toString(), cartInfoExist);

    }

    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        //  声明一个集合来存储数据：
        List<CartInfo> noLoginCartInfoList = new ArrayList<>();

        //  未登录： 只有临时用户Id ，没有userId！ 查询未登录购物车数据并排序返回！
        if (!StringUtils.isEmpty(userTempId)){
            //  从缓存中获取数据！
            //  获取购物车key
            String cartKey = this.getCartKey(userTempId);
            //  hset key field hget key field  hgetAll key [ key value ]  hvals key [value]
            noLoginCartInfoList = this.redisTemplate.opsForHash().values(cartKey);
            //  cartInfoList =  this.redisTemplate.boundHashOps(cartKey).values();
        }
        //  排序： 按照修改的时间进行排序！
        if (StringUtils.isEmpty(userId)){
            if (!CollectionUtils.isEmpty(noLoginCartInfoList)){
                noLoginCartInfoList.sort((o1, o2) -> {
                    //  返回比较结果！
                    return o2.getUpdateTime().compareTo(o1.getUpdateTime());
                    //  return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
                });
            }
            return noLoginCartInfoList;
        }

        /*
            登录：
                case 1: userId userTempId
                case 2: userId
         */
        //  声明一个登录购物车集合：
        //  获取购物车key
        String cartKey = this.getCartKey(userId);
        //  获取登录购物车数据！
        BoundHashOperations<String,String,CartInfo> boundHashOperations = this.redisTemplate.boundHashOps(cartKey);
        //  判断未登录购物车集合有数据！
        if (!CollectionUtils.isEmpty(noLoginCartInfoList)){
            noLoginCartInfoList.stream().forEach(cartInfo -> {
                //  if (cartInfo.getSkuId().intValue()==info.getSkuId().intValue()){
                //  21,22,23
                if (boundHashOperations.hasKey(cartInfo.getSkuId().toString())){
                    //  说明有相同的skuId！ hget key field;
                    CartInfo cartInfoLogin = boundHashOperations.get(cartInfo.getSkuId().toString());
                    //  修改数量
                    cartInfoLogin.setSkuNum(cartInfoLogin.getSkuNum()+cartInfo.getSkuNum());
                    //  修改时间
                    cartInfoLogin.setUpdateTime(new Date());
                    //  查询一下实时价格
                    cartInfoLogin.setSkuPrice(this.productFeignClient.getSkuPrice(cartInfo.getSkuId()));
                    //  选中..... 未登录状态为1 ，则修改登录选中状态！
                    if (cartInfo.getIsChecked().intValue()==1){
//                        if (cartInfoLogin.getIsChecked().intValue()==0){
//                            cartInfoLogin.setIsChecked(1);
//                        }
                        //  将数据库的选中状态赋值为1
                        cartInfoLogin.setIsChecked(1);
                    }
                    //  写入进去！
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfoLogin);
                }else {
                    //  不行！ 24
                    cartInfo.setUserId(userId);
                    cartInfo.setCreateTime(new Date());
                    cartInfo.setUpdateTime(new Date());
                    //  写入进去！
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            });
            //  删除临时购物车数据：
            this.redisTemplate.delete(this.getCartKey(userTempId));
        }

        //  查询最终合并之后的数据结果集： hvlas key;
        List<CartInfo> loginCartInfoList = boundHashOperations.values();
        //  判断
        if(CollectionUtils.isEmpty(loginCartInfoList)){
            //  默认返回空集合
            return new ArrayList<>();
        }

        //  排序：
        loginCartInfoList.sort((o1, o2) -> {
            //  返回比较结果！
            return o2.getUpdateTime().compareTo(o1.getUpdateTime());
        });

        //  使用集合包含关系！
        //  判断
        //        if (!StringUtils.isEmpty(userId)){
        //            //  从缓存中获取数据！
        //            //  获取购物车key
        //            String cartKey = this.getCartKey(userId);
        //            //  hset key field hget key field  hgetAll key [ key value ]  hvals key [value]
        //            loginCartInfoList = this.redisTemplate.opsForHash().values(cartKey);
        //            //  判断未登录购物车集合
        //            if (!CollectionUtils.isEmpty(noLoginCartInfoList)){
        //                for (CartInfo cartInfo : noLoginCartInfoList) {
        //                    for (CartInfo info : loginCartInfoList) {
        //                        if (cartInfo.getSkuId().intValue()==info.getSkuId().intValue()){
        //                            //  数量相加 ， 更新修改时间 ....  21,22,23
        //                        }else {
        //                            //  insert ! createTime updateTime 24
        //                        }
        //                    }
        //                }
        //                //  删除未登录购物车数据：
        //                this.redisTemplate.delete(this.getCartKey(userTempId));
        //            }
        //            //  再查一次！
        //            loginCartInfoList = this.redisTemplate.opsForHash().values(cartKey);
        //            //  排序！
        //        }

        return loginCartInfoList;

    }

    @Override
    public void checkCart(Long skuId, String userId, Integer isChecked) {
        //  修改数据！
        //  获取key
        String cartKey = this.getCartKey(userId);

        //  先根据key 来获取数据！ hget key field
        CartInfo cartInfo = (CartInfo) this.redisTemplate.opsForHash().get(cartKey, skuId.toString());
        //  判断
        if (cartInfo!=null){
            cartInfo.setIsChecked(isChecked);
        }
        //  放入缓存！
        this.redisTemplate.opsForHash().put(cartKey,skuId.toString(),cartInfo);

    }

    @Override
    public void deleteCart(Long skuId, String userId) {
        //  hdel key field
        //  获取购物车key
        String cartKey = this.getCartKey(userId);

        //  可以通过先判断key 是否存在，再决定是否删除！  与 直接删除 一样！
        //  Boolean aBoolean = this.redisTemplate.opsForHash().hasKey(cartKey, skuId.toString());
        //  this.redisTemplate.opsForHash().delete(cartKey,skuId.toString());

        //        BoundHashOperations boundHashOperations = this.redisTemplate.boundHashOps(cartKey);
        //        if (boundHashOperations.hasKey(skuId.toString())){
        //            //  删除数据！
        //            boundHashOperations.delete(skuId.toString());
        //        }
        //  删除数据！
        this.redisTemplate.boundHashOps(cartKey).delete(skuId.toString());

    }

    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        //  选中状态列表！ is_checked = 1;
        //  获取缓存的key
        String cartKey = this.getCartKey(userId);
        //  hvals key
        List<CartInfo> cartInfoList = this.redisTemplate.opsForHash().values(cartKey);

        List<CartInfo> cartInfoCheckedList = new ArrayList<>();
        //  判断
//        if (!CollectionUtils.isEmpty(cartInfoList)){
//            //  遍历当前集合
//            cartInfoCheckedList = cartInfoList.stream().map(cartInfo -> {
//                if (cartInfo.getIsChecked().intValue() == 1) {
//                    return cartInfo;
//                }
//                return new CartInfo();
//            }).collect(Collectors.toList());
//        }
        //  返回数据
//        return cartInfoCheckedList;
        cartInfoCheckedList = cartInfoList.stream().filter(cartInfo -> {
            //  表示获取到当前选中的商品！
            //            if (cartInfo.getIsChecked().intValue() == 1){
            //                //  查询商品最新价格！
            //                cartInfo.setSkuPrice(this.productFeignClient.getSkuPrice(cartInfo.getSkuId()));
            //                return true;
            //            }
            //  查询所有商品最新价格！
            cartInfo.setSkuPrice(this.productFeignClient.getSkuPrice(cartInfo.getSkuId()));

            return cartInfo.getIsChecked().intValue() == 1;
        }).collect(Collectors.toList());

        //  返回数据
        return cartInfoCheckedList;
    }

    /**
     * 获取购物车key
     *
     * @param userId
     * @return
     */
    private String getCartKey(String userId) {
        return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
    }
}
